\section{Desarrollo}
El desarrollo del trabajo tuvo dos etapas: la implementación en lenguaje C del compresor, y su posterior traducción a lenguaje ensamblador.\\

La versión en C funcionando correctamente, nos facilito la tarea de la implementación en assembler y su respectivo proceso de testing y corrección de errores. Se decidió programar completamente esta versión antes de escribir cualquier función en assembler, para evitar errores en los algoritmos mismos. Al ser correctos en C, serán correctos en assembler.\\

 Para buscar y corregir errores, usamos las herramientas Valgrind para revisar si existia memoria no liberada y GDB para el analisis paso por paso del funcionamiento del programa. A continuación, y en las siguientes secciones, detallaremos lo trabajado.

\subsection{Implementaci\'on preliminar en lenguaje C}

Esta versi\'on buscaba implementar todas las funciones requeridas en lenguaje de alto nivel para luego utilizarla 
como gu\'ia para escribir el c\'odigo en \keyword{assembler}. \\
Se crearon dos archivos para la programación en C: definiciones.h e implementaciones.h. El primero contiene todas las estructuras y declaraciones de las funciones dadas en el enunciado, mientras que el segundo contiene el código de las funciones en sí. \\

A la hora de la programación de las funciones, decidimos dar un enfoque propio y diferente a cada una. Como por ejemplo para crear el algoritmo que maneja datos a nivel de bits, por un lado se usó una estructura Bit que es un Bitfield de un solo bit, mientras que en otra función se usaron puramente shifts lógicos y operaciones de módulo. Este último algoritmo fue el que resultó para la implementación en ensamblador (junto con alguna que otra funcionalidad que proveen las instrucciones de Intel). \\

Una vez escrito el c\'odigo en C, \'este se aprovech\'o para ir reemplazando funci\'on a funci\'on con c\'odigo ensamblador, 
porque se pod\'ia asumir que el c\'odigo de alto nivel era correcto. Esto nos permiti\'o probar que las funciones 
en ensamblador se comportaban adecuadamente ya que deb\'ian igualar el comportamiento de las funciones reemplazadas, incluyendo los posibles errores de manejo y liberación de memoria.\\

El rendimiento de la aplicación escrita en C es casi tan veloz como la de ensamblador, como se verá en la sección de tests.


\subsection{Implementaci\'on en lenguaje ensamblador}
Se decidi\'o separar la implementaci\'on \keyword{assembler} en varios archivos espec\'ificos: uno por cada función a 
implementar y un archivo exclusivamente de macros para facilitar ciertas tareas como ser el manejo de la pila según la convención C o imprimir errores y devolver un código de error al programa. \\

La ventaja de tener las funciones separadas en diferentes archivos es facilitar el proceso de correción de errores y a su vez escribir un código mas prolijo. Si una función causaba problemas, se podia separar y usar su versión en C para comparar y buscar diferencias. \\

El orden de implementación de las funciones no era relevante, pudimos programar cualquier función ya que se podia depender del código en C. La mayoria de las funciones tienen variables locales, lo cual implica muchos accesos a memoria y es una razon principal de porque el rendimiento no se diferencia mucho de la implementación en C. Por otro lado creemos que el hecho de tener que copiar todo el archivo a memoria al comenzar el proceso ocupa una parte importante del tiempo de ejecución.



\pagebreak
